using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace Jerry.UiFrame.Editor
{
    /// <summary>
    /// 用于自动化生成UI基类
    /// </summary>
    [ExecuteInEditMode]
    public class GenUIBase
    {
        private static string _baseClassPath;
        private static string _prefabPath;
        private static string _uiScriptsPath;

        static List<string> _exportGos = new List<string>();

        [MenuItem("GameObject/生成UI基类", false, -1)]
        static void GenericBase()
        {
            if (!GetUiConfig())
            {
                CreateAsset.ShowWindow();
                return;
            }
            
            _exportGos.Clear();
            var go = Selection.activeGameObject;

            if (go == null)
            {
                Debug.LogError("请选中一个GameObject!!!!");
                return;
            }
            
            if (go.name.StartsWith("UI") && go.name.EndsWith("Win"))
            {
                GetChildren(go);

                CreateBaseCSharp(go);
                CreateUiCSharp(go);

                //把选中的物体弄成预制体
                PrefabUtility.SaveAsPrefabAsset(go, _prefabPath + go.name + ".prefab");

                // FileSaveLoad.SaveToText(sb.ToString(), $"{baseClassPath}Base{go.name}.cs");
                AssetDatabase.Refresh();
            }
            else
            {
                Debug.LogError("选中的物体不是UI界面");
            }
        }

        #region 找到所有子物体

        private static void GetChildren(GameObject parent)
        {
            if (parent == null)
            {
                Debug.LogError("没有选到物体");
                return;
            }

            // 遍历所有直接子物体
            foreach (Transform child in parent.transform)
            {
                string path = parent.name + "/" + child.name;
                _exportGos.Add(path);
                // 递归处理子物体的子物体
                TraverseChildren(child, path);
            }
        }

        private static void TraverseChildren(Transform current, string currentPath)
        {
            foreach (Transform child in current)
            {
                string childPath = currentPath + "/" + child.name;
                _exportGos.Add(childPath);
                TraverseChildren(child, childPath);
            }
        }

        #endregion

        static AllPaths IsHasUiConfig()
        {
            var path = "Assets/Resources/UiPathConfig.asset";
            var asset = AssetDatabase.LoadAssetAtPath<AllPaths>(path);
            return asset;
        }

        static bool GetUiConfig()
        {
            AllPaths asset = IsHasUiConfig();
            if (asset != null)
            {
                _baseClassPath = asset.baseUiScriptsPath;
                _prefabPath = asset.prefabPath;
                _uiScriptsPath = asset.uiScriptsPath;
                return true;
            }

            return false;
        }

        /// <summary>
        /// 创建C#基类脚本
        /// </summary>
        /// <param name="go">选中的物体</param>
        static void CreateBaseCSharp(GameObject go)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("using Jerry.UiFrame;\n");
            sb.Append("using UnityEngine;\n");
            sb.Append("namespace UI.Base\n");
            sb.Append("{\n");
            sb.Append($"\tpublic class Base{go.name} : UIBase\n");
            sb.Append("\t{\n");
            foreach (var item in _exportGos)
            {
                var temp = item.Split("/");
                if (temp[^1].StartsWith("Btn_"))
                {
                    sb.Append($"\t\tprotected JButton {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("Img_"))
                {
                    sb.Append($"\t\tprotected JImage {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("List_"))
                {
                    sb.Append($"\t\tprotected JList {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("Slider_"))
                {
                    sb.Append($"\t\tprotected JSlider {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("Text_"))
                {
                    sb.Append($"\t\tprotected JText {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("TMP_"))
                {
                    sb.Append($"\t\tprotected JTextMesh {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("Toggle_"))
                {
                    sb.Append($"\t\tprotected JToggle {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("Panel_"))
                {
                    sb.Append($"\t\tprotected GameObject {temp[^1]};\n");
                }

                if (temp[^1].StartsWith("Input_"))
                {
                    sb.Append($"\t\tprotected JInput {temp[^1]};\n");
                }
               
                if (temp[^1].StartsWith("InputTMP_"))
                {
                    sb.Append($"\t\tprotected JInputTMP {temp[^1]};\n");
                }
                
                if (temp[^1].StartsWith("Drop_"))
                {
                    sb.Append($"\t\tprotected JDropdown {temp[^1]};\n");
                }
                
                if (temp[^1].StartsWith("DropTMP_"))
                {
                    sb.Append($"\t\tprotected JDropdownTMP {temp[^1]};\n");
                }
            }

            sb.Append($"\t\tprotected override void Awake()\n");
            sb.Append("\t\t{\n");
            foreach (var item in _exportGos)
            {
                var temp = item.Split("/");
                var item1 = item.Replace(go.name + "/", "");
                if (temp[^1].StartsWith("Btn_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JButton>();\n");
                }

                if (temp[^1].StartsWith("Img_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JImage>();\n");
                }

                if (temp[^1].StartsWith("List_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JList>();\n");
                }

                if (temp[^1].StartsWith("Slider_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JSlider>();\n");
                }

                if (temp[^1].StartsWith("Text_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JText>();\n");
                }

                if (temp[^1].StartsWith("TMP_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JTextMesh>();\n");
                }

                if (temp[^1].StartsWith("Toggle_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JToggle>();\n");
                }
                
                if (temp[^1].StartsWith("Panel_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").gameObject;\n");
                }
                
                if (temp[^1].StartsWith("InputTMP_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JInputTMP>();\n");
                }
                
                if (temp[^1].StartsWith("Input_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JInput>();\n");
                }
                
                if (temp[^1].StartsWith("Drop_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JDropdown>();\n");
                }
                
                if (temp[^1].StartsWith("DropTMP_"))
                {
                    sb.Append($"\t\t\t{temp[^1]} = transform.Find(\"{item1}\").GetComponent<JDropdownTMP>();\n");
                }
            }

            sb.Append("\t\t\tbase.Awake();\n");
            sb.Append("\t\t}\n");
            sb.Append("\t}\n");
            sb.Append("}\n");

            var path = $"{_baseClassPath}Base{go.name}.cs";
            
            try
            {
                StreamWriter sw = new StreamWriter(path);
                sw.Write(sb.ToString());
                sw.Close();
            }
            catch(Exception e)
            {
                throw new Exception(e.ToString());
            }
            finally
            {
            }
        }

        /// <summary>
        /// 创建UI类
        /// </summary>
        /// <param name="go"></param>
        static void CreateUiCSharp(GameObject go)
        {
            //检测文件是否存在
            var path = $"{_uiScriptsPath}{go.name}.cs";
            if (!File.Exists(path))
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("using UI.Base;\n\n");
                sb.Append("namespace UI.Win\n");
                sb.Append("{\n");
                sb.Append("\t");
                sb.Append($"public class {go.name} : Base{go.name}\n");
                sb.Append("\t{\n");
                sb.Append("\t\tprotected override void OnInitData()\n");
                sb.Append("\t\t{\n");
                sb.Append("\t\t}\n");
                sb.Append("\t}\n");
                sb.Append("}");
            
                try
                {
                    StreamWriter sw = new StreamWriter(path);
                    sw.Write(sb.ToString());
                    sw.Close();
                }
                catch(Exception e)
                {
                    throw new Exception(e.ToString());
                }
                finally
                {
                }
            }
        }
    }
}